# coding=utf-8
import tornado.ioloop
import tornado.httpserver
import tornado.options
import tornado.web
import tornado.httpclient
import tornado.gen
from tornado.concurrent import run_on_executor
# 这个并发库在python3自带;在python2需要安装sudo pip install futures
from concurrent.futures import ThreadPoolExecutor
import time
#from tornado.options import define, options
#define("port", default=8002, help="run on the given port", type=int)

from aip import AipBodyAnalysis
import requests
import numpy as np
import cv2
import os
import json
import sys  
reload(sys)  
sys.setdefaultencoding('utf8')  

from Beauty import Beauty
from PIL import Image


def longleg2(result, path, name):
    #body = result['person_info'][0]['body_parts']
    def get_y(result):
        """
        先识别臀部y 再识别膝盖y 取靠近者三分之一处
        """
        for i in result['person_info']:
            body = i['body_parts']
            l_hip = int(body['left_hip']['y'])
            r_hip = int(body['right_hip']['y'])
            if l_hip >= r_hip: 
                l_knee = int(body['left_knee']['y'])
                return int(l_knee - (int(l_knee - l_hip)/3))
            else: 
                r_knee = int(body['right_knee']['y'])
                return int(r_knee - (int(r_knee - r_hip)/3))
    y = get_y(result)
    print y
    im = Image.open(path)
    up_region= im.crop((0, 0, im.size[0], y))
    below_region= im.crop((0, y, im.size[0], im.size[1]))
    print im.size[1]-y
    below_region = below_region.resize((below_region.size[0], int(below_region.size[1]*1.1)))
    print below_region.size[1]
    target = Image.new('RGB', (im.size[0], (below_region.size[1]+ up_region.size[1])))    
    target.paste(up_region,(0, 0))
    target.paste(below_region,(0, up_region.size[1]))
    target.save(path)
        
def longleg(result, path, name):
    knee_long = 20
    ankle_long = 40
    deform = list()
    #body = result['person_info'][0]['body_parts']
    for i in result['person_info']:
        body = i['body_parts']
        l_hip = [int(body['left_hip']['x']), int(body['left_hip']['y'])]
        l_hip2 = [x for x in l_hip]
        l_hip.extend(l_hip2)
        
        r_hip = [int(body['right_hip']['x']), int(body['right_hip']['y'])]
        r_hip2 = [x for x in r_hip]
        r_hip.extend(r_hip2)

        l_knee = [int(body['left_knee']['x']), int(body['left_knee']['y'])]
        l_knee2 = [x + knee_long for x in l_knee]
        l_knee2[0] = l_knee[0]
        l_knee.extend(l_knee2)

        l_ankle = [int(body['left_ankle']['x']), int(body['left_ankle']['y'])]
        l_ankle2 = [x + ankle_long for x in l_ankle]
        l_ankle2[0] = l_ankle[0]
        l_ankle.extend(l_ankle2)

        r_knee = [int(body['right_knee']['x']), int(body['right_knee']['y'])]
        r_knee2 = [x + knee_long for x in r_knee]
        r_knee2[0] = r_knee[0]
        r_knee.extend(r_knee2)

        r_ankle = [int(body['right_ankle']['x']), int(body['right_ankle']['y'])]
        r_ankle2 = [x + ankle_long for x in r_ankle]
        r_ankle2[0] = r_ankle[0]
        r_ankle.extend(r_ankle2)
        
        l_wrist = [int(body['left_wrist']['x']), int(body['left_wrist']['y']), int(body['left_wrist']['x']), int(body['left_wrist']['y'])]
        r_wrist = [int(body['right_wrist']['x']), int(body['right_wrist']['y']), int(body['right_wrist']['x']), int(body['right_wrist']['y'])]
        info = [l_knee, l_ankle, r_knee, r_ankle, r_hip, l_hip, l_wrist, r_wrist]
        deform.extend(info)
    with open(path[:-4]+ '.json', 'wb') as f: f.write(json.dumps(deform))
    os.system('node demo.js %s %s %s'%(path[:-4]+'.json', path, path))

def draw(result, path):
    img = cv2.imread(path)
    body_parts = result['person_info'][1]['body_parts']
    for k, v in body_parts.items():
        img = cv2.circle(img, (int(v['x']), int(v['y'])), 3, (0, 0, 255), 3)
        print k
    cv2.imwrite(path, img)





def get_point(path='test2.png'):
    """ 你的 APPID AK SK """
    APP_ID = '11621236'
    API_KEY = 'wHC5Hyj9M3jOu1sin5rs8EjD'
    SECRET_KEY = 'SG9G3PFj7HZpoIrCAW1OZ6SauPAm0L3K'
    client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
    """ 读取图片 """
    def get_file_content(filePath):
        with open(filePath, 'rb') as fp:
            return fp.read()
    image = get_file_content(path)
    """ 调用人体关键点识别 """
    result = client.bodyAnalysis(image);
    name = path[:-4]+'new.png'
    #draw(result, path)
    longleg2(result, path, name)
    #return path
    return path



class Skin(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(1) #起线程池，由当前RequestHandler持有
    def get(self):
        self.render("html2.html")

    @tornado.gen.coroutine
    def post(self):
        upload_path=os.path.join(os.path.dirname(__file__),'static/images')  #文件的暂存路径
        file_metas=self.request.files['file']    #提取表单中‘name’为‘file’的文件元数据
        for meta in file_metas:
            filename=meta['filename']
            filepath=os.path.join(upload_path,str(int(time.time())) + '.' + filename.split('.')[-1])
            with open(filepath,'wb') as up:      #有些文件需要已二进制的形式存储，实际中可以更改
                up.write(meta['body'])
        result = yield self.block_task(filepath) #block_task将提交给线程池运行
        self.write('<div class="imgshow"><img src="http://120.132.68.29:8888/%s" alt=""  width="400"></div>'%result) 
    
    @run_on_executor
    def block_task(self, path):
        result = get_point(path) 
        Beauty(result, result).buffing(grade=3, b_skin=True)
        return result #直接return结果即可

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("html.html")

class LongLeg(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(1) #起线程池，由当前RequestHandler持有
    @tornado.gen.coroutine
    def get(self):
        path = self.get_argument('path')
        path=os.path.join(os.path.dirname(__file__), path),
        #url = 'http://tupshow.com.tw/images/albums/tupshow2015com/t2z5k6i1ac/15154914388e54c1d97ec3e25e.jpg'
        #url = 'http://www.people.com.cn/mediafile/pic/20141217/37/15707537969555694337.jpg'
        result = yield self.block_task(path) #block_task将提交给线程池运行
        self.write(result)
    
    @run_on_executor
    def block_task(self, path):
        result = get_point(path)   
        return result #直接return结果即可
 

class UploadFileHandler(tornado.web.RequestHandler):
    executor = ThreadPoolExecutor(1) #起线程池，由当前RequestHandler持有
    def get(self):
        self.write('''
        <html>
        <head><title>Upload File</title></head>
        <body>
        <form action='file' enctype="multipart/form-data" method='post'>
        <input type='file' name='file'/><br/>
        <input type='submit' value='submit'/>
        </form>
        </body>
        </html>
        ''')

    @tornado.gen.coroutine
    def post(self):
        upload_path=os.path.join(os.path.dirname(__file__),'static/images')  #文件的暂存路径
        file_metas=self.request.files['file']    #提取表单中‘name’为‘file’的文件元数据
        for meta in file_metas:
            filename=meta['filename']
            filepath=os.path.join(upload_path,str(int(time.time())) + '.' + filename.split('.')[-1])
            with open(filepath,'wb') as up:      #有些文件需要已二进制的形式存储，实际中可以更改
                up.write(meta['body'])
        result = yield self.block_task(filepath) #block_task将提交给线程池运行
        self.write('<div class="imgshow"><img src="http://120.132.68.29:8888/%s" alt=""  width="400"></div>'%result) 
    @run_on_executor
    def block_task(self, path):
        result = get_point(path) 
        Beauty(result, result).buffing(grade=3)
        return result #直接return结果即可

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
        (r'/file',UploadFileHandler),
        (r"/longleg", LongLeg),
        (r"/skin", Skin)
        ],

        static_path=os.path.join(os.path.dirname(__file__), "static"),
        template_path=os.path.join(os.path.dirname(__file__), "static/templates")
        )

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()
